﻿
namespace TFSChangeLog.ViewModel
{
    using System;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Linq;
    using TFSChangeLog.DataModel;

    /// <summary>Summary description for <see cref="BranchViewModel"/> class.</summary>
    public class BranchViewModel : INotifyPropertyChanged
    {
        #region Data
        /// <summary>Summary description for class level field of type <c>System.Collections.ObjectModel.ObservableCollection{TFSChangeLog.ViewModel.BranchViewModel}</c>.</summary>
        private readonly ObservableCollection<BranchViewModel> _children;

        /// <summary>Summary description for class level field of type <c>TFSChangeLog.ViewModel.BranchViewModel</c>.</summary>
        private readonly BranchViewModel _parent;

        /// <summary>Summary description for class level field of type <c>TFSChangeLog.DataModel.Branch</c>.</summary>
        private readonly Branch _branch;

        /// <summary>Summary description for class level field of type <c>bool</c>.</summary>
        private bool _isExpanded;

        /// <summary>Summary description for class level field of type <c>bool</c>.</summary>
        private bool _isSelected;
        #endregion 

        #region Constructors

        /// <summary>Initializes a new instance of the <see cref="BranchViewModel"/> class.</summary>
        /// <param name="branch">TODO: Summary description for <c>branch</c> parameter of type <c>TFSChangeLog.DataModel.Branch</c>.</param>
        public BranchViewModel(Branch branch)
            : this(branch, null)
        {
        }

        /// <summary>Initializes a new instance of the <see cref="BranchViewModel"/> class.</summary>
        /// <param name="branch">TODO: Summary description for <c>branch</c> parameter of type <c>TFSChangeLog.DataModel.Branch</c>.</param>
        /// <param name="parent">TODO: Summary description for <c>parent</c> parameter of type <c>TFSChangeLog.ViewModel.BranchViewModel</c>.</param>
        private BranchViewModel(Branch branch, BranchViewModel parent)
        {
            this._branch = branch;
            this._parent = parent;
            if (this._parent != null)
                {
                    this._parent.IsExpanded = true;
                }

            this._children = new ObservableCollection<BranchViewModel>(
                    (from child in this._branch.Children
                     select new BranchViewModel(child, this))
                     .ToList<BranchViewModel>());
        }

        #endregion

        #region Properties

        /// <summary>Gets the value for Children.</summary>
        public ObservableCollection<BranchViewModel> Children
        {
            get { return this._children; }
        }

        /// <summary>Gets the value for Name.</summary>
        public string Name
        {
            get { return this._branch.Name; }
        }

        /// <summary>Gets or sets a value indicating whether (TODO: Fix the documentation here) :: Gets/sets whether the TreeViewItem 
        /// associated with this object is expanded.</summary>
        public bool IsExpanded
        {
            get
            {
                return this._isExpanded;
            }

            set
            {
                if (value != this._isExpanded)
                {
                    this._isExpanded = value;
                    this.OnPropertyChanged("IsExpanded");
                }

                // Expand all the way up to the root.
                if (this._isExpanded && this._parent != null)
                    {
                        this._parent.IsExpanded = true;
                    }
            }
        }

        /// <summary>Gets or sets a value indicating whether (TODO: Fix the documentation here) :: Gets/sets whether the TreeViewItem 
        /// associated with this object is selected.</summary>
        public bool IsSelected
        {
            get
            {
                return this._isSelected;
            }

            set
            {
                if (value != this._isSelected)
                {
                    this._isSelected = value;
                    this.OnPropertyChanged("IsSelected");
                }
            }
        }

        /// <summary>Summary description for <c>BranchViewModel</c> method.</summary>
        /// <param name="text">TODO: Summary description for <c>text</c> parameter of type <c>string</c>.</param>
        /// <returns>TODO: returns an object of type <c>bool</c>.</returns>
        public bool NameContainsText(string text)
        {
            if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(this.Name))
                {
                    return false;
                }

            return this.Name.IndexOf(text, StringComparison.InvariantCultureIgnoreCase) > -1;
        }

        /// <summary>Gets the value for Parent.</summary>
        public BranchViewModel Parent
        {
            get { return this._parent; }
        }

        #endregion

        #region INotifyPropertyChanged Members

        /// <summary>Summary description for <c>PropertyChanged</c> event.</summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>Summary description for <c>BranchViewModel</c> method.</summary>
        /// <param name="propertyName">TODO: Summary description for <c>propertyName</c> parameter of type <c>string</c>.</param>
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
        }

        #endregion // INotifyPropertyChanged Members
    }
}
